Pod 是經過 kube-scheduler 排程到 Node,但是如果要制定靈活的策略要怎麼辦?如果我的應用情境跟其他資源相關,比如說智慧城市以及智慧工廠,我要怎麼按照特殊需求開發排程策略讓 kubernetes 遵守?
在之前,Kuberntes 排程是依靠 extension,Filter, Prioritize, Preempt, Bind 都有各自的 Extension 實作,如果要在這些階段加入複雜的邏輯,需要自己修改,或是開發 webhook 讓各自的 extension 調用,但是這樣會有以下問題:
於是 kube-scheduler 引入 Scheduler Framework,Scheduler Framework 利用 go plugins 提供擴充性,讓開發的 plugin 在編譯的時候放入 kube-scheduler,並在運行的時候用配置開關。
Scheduler Framework 把排程一個 Pod 的過程分成兩個時期,第一個是 Scheduling Cycle,第二個是 Binding Cycle,Scheduling Cycle 主要包含前面提到的 Filter 以及 Score 兩階段,Scheduling Cycle 會幫 Pod 選擇一個 Node,然後 binding cycle 會負責把 Pod 排程到這個 Node 上。
當一個 Pod 進到 kube-scheduler,挑選一個 Node,把 Pod 排程上去,這一整個過程,走過 Scheduling Cycle 以及 Binding Cycle,這在 Scheduler Framework 中被稱為 Scheduler Context。
值得注意的是 Scheduling Cycle 的執行順序是循序的,同一時間只會運行一個 Scheduling Cycle,這意味只有前一個 Scheduler Cycle 結束之後才會開始下一個 Scheduler Cycle,如果你的 Node 數量極大,會導致 Scheduling Cycle 的運算時間過久,甚至會 casede 到後面的 Pod,在最壞的情況下,你會發現 HPA 已經 scale out Pod,但是因為 Node 數量太多,所以五分鐘之後才看到 Pod 排程出去,這時候的 P0 已經跳到全世界都失火了。
要解決 Node 數量極大造成的 Scheduler Cycle 過久的問題,可以對 kube-scheduler 設定 percentageOfNodesToScore,其作用是讓 kube-scheduler 不要計算全部的Node,可以計算部分 Node 就好。
以下為設定範例:
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
provider: DefaultProvider
...
percentageOfNodesToScore: 50
以這個設定為例,假設有 100 Node,就只會計算 50 Node 然後挑選這 50 Node 裡面的最高分進入 Binding Cycle。
percentageOfNodesToScore 只有在 100 個以上節點的時候有效,這是一個 Hardcoded 的數字。
percentageOfNodesToScore 建議設定大於 10%,不然有可能會出現 Pod 分佈過於不均勻的狀態,但如果你非常需要快速排程,而且並不在意是哪一個 Node 運行這個 Pod,你還是可以設定小數值。
Ref:
KEP of Scheduler Framework
percentageOfNodesToScore
https://kubernetes.io/docs/concepts/scheduling-eviction/scheduler-perf-tuning/